﻿@page "/neuralnet"
@using ML5
@inject IJSRuntime Runtime
@inject HttpClient Http

<div>
    <h2 style="color:forestgreen">Neural Network</h2><br />
    <h5>Titanic Dataset Example</h5>
    <br />
    <br />
</div>
<div>
    @if (trained)
    {
        <center>
            <div class="card" style="width: 38rem;">
                <ul class="list-group list-group-flush">
                    <li class="list-group-item">
                        Gender
                        <select class="form-control" @bind="gender">
                            <option value="male" selected>male</option>
                            <option value="female">female</option>
                        </select>
                    </li>
                    <li class="list-group-item">
                        Fare Class
                        <select class="form-control" @bind="fare_class">
                            <option value="first" selected>first</option>
                            <option value="second">second</option>
                            <option value="third">third</option>
                        </select>
                    </li>
                    <li class="list-group-item">
                        Age  (Yrs)
                        <form onsubmit="return false;">
                            <input type="number" min="01" max="100" class="form-control" @bind-value="age">
                        </form>

                    </li>
                    <li class="list-group-item">
                        Fare
                        <form onsubmit="return false;">
                            <input type="number" min="0" max="300" class="form-control" @bind-value="fare">
                        </form>
                    </li>
                    <li class="list-group-item">
                        <button class="btn btn-primary" type="submit" @onclick="classify">Predict</button>
                    </li>
                    <li class="list-group-item">
                        @if (Result != null)
                        {
                            <div class="alert alert-@(Result.IndexOf("died") >= 0 ? "danger" : "primary")" role="alert">
                                Prediction: @Result
                            </div>
                        }
                    </li>
                </ul>
            </div>

        </center>
    }
    else
    {

        <div class="alert alert-primary" role="alert">
            Loading and Training Dataset, please have patience
        </div>
    }
</div>



@if (dataset != null)
{
    <p style="color:black;font-size:medium">Training DataSet Size : @dataset.Length</p>
    <p style="color:black;font-size:medium">Dataset is bit small, train for longer time</p>

}

@code {

    bool trained = false;
    string Result;
    NeuralNetwork network;
    Data[] dataset;
    int age, fare;
    string fare_class, gender;

    protected override Task OnInitializedAsync()
    {
        fare_class = "first"; gender = "male";
        NeuralNetworkOptions option = new NeuralNetworkOptions()
        {
            inputs = 4,
            outputs = 1,
            task = NetworkTask.classification,
            debug = true
        };
        network = new NeuralNetwork(Runtime, option);
        network.OnClassification += OnClassify;
        network.OnTrainingComplete += OnTrained;
        Loaddata();
        return base.OnInitializedAsync();
    }

    void classify()
    {
        network.Classify(new object[] { age, fare, fare_class, gender });
    }

    async void Loaddata()
    {
        dataset = await Http.GetFromJsonAsync<Data[]>("data/titanic.json");
        foreach (var data in dataset)
        {
            network.AddData(new object[] { data.age, data.fare, data.fare_class,data.sex }, new object[] { data.survived });
        }
        network.NormalizeData();

        Console.WriteLine("Added Dataset of size : " + dataset.Length);

        StartTrain();
    }
    void OnTrained()
    {
        trained = true;
        StateHasChanged();
    }

    void StartTrain()
    {
        TrainingOptions options = new TrainingOptions()
        {
            epochs = 10,
            batchSize = 32
        };
        network.Train(options);
    }


    void OnClassify(string error, CResult[] results)
    {
        Result = results[0].label;
        StateHasChanged();
    }

    class Data
    {
        public string survived { get; set; }
        public string fare_class { get; set; }
        public string sex { get; set; }
        public int age { get; set; }
        public int fare { get; set; }
    }
}
